package com.happy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.happy.common.utils.BeanHelper;
import com.happy.common.utils.HttpClientHelper;
import com.happy.dao.RequestMessageDao;
import com.happy.pojo.RequestMessage;
import com.happy.pojo.TestDetail;
import com.happy.pojo.User;
import com.happy.service.RequestMessageService;
import com.happy.service.TestDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import sun.util.PreHashedMap;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: happyin
 * @Date: 2021/9/27 11:54
 * @Version: 1.0
 */
@Transactional
@Service
public class RequestMessageServiceImpl implements RequestMessageService {
    @Autowired
    private RequestMessageDao requestMessageDao;
    @Autowired
    private TestDetailService testDetailService;

    @Override
    public int save(RequestMessage requestMessage, User user) {
        int result = 0;
        try {
            if (user == null) {//如果未登录,则不能保存测试案例
                throw new Exception("您尚未登录,不能保存测试案例");
            }
            //保存先判断名称是否已经存在
            List<RequestMessage> requestMessageList = requestMessageDao.selectByName(requestMessage.getRequestName());
            if (!CollectionUtils.isEmpty(requestMessageList)) {
                throw new Exception("案例名称已经存在");
            }
            requestMessage.setCreateUserId(user.getId());
            requestMessage.setCreateTime(new Date());
            requestMessage.setUpdateTime(new Date());
            requestMessage.setIsUsed("1");
            requestMessage.setversion(1);
            result = requestMessageDao.insertSelective(requestMessage);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        return result;
    }

    @Override
    public Map tryTest(RequestMessage requestMessage) {
        Map repMap;
        try {
            repMap = HttpClientHelper.doHttpRequset(BeanHelper.entityToMap(requestMessage));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return repMap;
    }

    @Override
    public String test(RequestMessage requestMessage, User user) {
        Map repMap;
        try {
            RequestMessage requestMessageFromDb = requestMessageDao.selectByPrimaryKey(requestMessage.getId());
            if (requestMessageFromDb == null) {
                throw new Exception("测试案例不存在或已被删除");
            }
            Date startTime = new Date();
            repMap = HttpClientHelper.doHttpRequset(BeanHelper.entityToMap(requestMessageFromDb));
            Date endTime = new Date();
            String responseBody = repMap.get("responseMsg").toString();
            TestDetail testDetail = new TestDetail();
            testDetail.setResponseBody(responseBody);
            testDetail.setRequestMessageId(requestMessageFromDb.getId());
            testDetail.setStartTime(startTime);
            testDetail.setEndTime(endTime);
            testDetail.setTestStartTime(startTime);
            testDetail.setTestEndTime(endTime);
            testDetail.setTestUseTime(endTime.getTime() - startTime.getTime());
            testDetail.setTestUserId(user.getId());

            //判断返回数据是否为json类型
            JSONObject responseJson = null;
            try {
                responseJson = JSONObject.parseObject(responseBody);
                //判断测试结果是否成功
                if (StringUtils.isEmpty(requestMessageFromDb.getsuccessFlag())) {
                    //如果案例中没有成功标识,则认为任何返回结果都是成功的
                    testDetail.setIsSuccess("1");
                } else {
                    //如果案例中有成功标识,则需要将返回结果和成功标识对比(如果一直则认为返回结果是成功的)
                    //获取成功校验规则,并转化为map对象
                    JSONObject successFlagJson = JSONObject.parseObject(requestMessageFromDb.getsuccessFlag());
                    Set<String> checkKeys = successFlagJson.keySet();
                    boolean flag = true;
                    //判断返回结果是否符合成功校验规则
                    for (String checkKey : checkKeys) {
                        if (!Objects.equals(responseJson.get(checkKey), successFlagJson.get(checkKey))) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        testDetail.setIsSuccess("1");
                    } else {
                        testDetail.setIsSuccess("0");
                    }
                }

            } catch (Exception e) {
                System.out.println("返回的数据不是json格式");
                testDetail.setIsSuccess("1");
            }


            testDetailService.save(testDetail);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return repMap.get("responseMsg").toString();
    }

    @Override
    public RequestMessage findById(Integer id) {

        RequestMessage requestMessage = null;
        try {
            requestMessage = requestMessageDao.selectByPrimaryKey(id);
            if (requestMessage == null) {
                throw new Exception("测试案例不存在或已被删除");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return requestMessage;
    }

    @Override
    public int delete(RequestMessage requestMessage, User user) {
        int result = 0;
        try {
            //1.查询该案例是否存在,如果不存在抛出异常
            requestMessage = requestMessageDao.selectByPrimaryKey(requestMessage.getId());
            if (requestMessage == null) {
                throw new RuntimeException("测试案例不存在或已被删除");
            }
            //2.查询该案例是否正在使用(从redis中获取,如果能获取到则证明),如果正在使用则不可被删除  todo  后期再实现
            //3.删除案例
            //3.1 删除测试案例本身
            int requestMessageNum = requestMessageDao.deleteByPrimaryKey(requestMessage.getId());
            //3.2 删除相关的测试详情
            int testDetailNum = testDetailService.deleteByRequestMessageId(requestMessage.getId());
            result = requestMessageNum == 0 ? requestMessageNum : testDetailNum;
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return result;
    }


}
